package shuimin.weixin;

import io.netty.handler.codec.http.multipart.DiskFileUpload;
import io.netty.util.CharsetUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import pond.common.JSON;
import pond.common.PATH;
import pond.common.S;
import pond.common.f.Callback;
import pond.web.http.MimeTypes;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * Created by sky on 16/5/17.
 */
public class HTTP {


    /**
     * post 上传图片
     *
     * @param uri
     * @param name
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static Map<String,Object> postImage(String uri, String name, InputStream inputStream,String type) throws IOException {
        /**
         * 第一部分
         */
        URL urlObj = new URL(uri);
        HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();

        /**
         * 设置关键值
         */
        con.setRequestMethod("POST"); // 以Post方式提交表单，默认get方式
        con.setDoInput(true);
        con.setDoOutput(true);
        con.setUseCaches(false); // post方式不能使用缓存

        // 设置请求头信息
        con.setRequestProperty("Connection", "Keep-Alive");
        con.setRequestProperty("Charset", "UTF-8");

        // 设置边界
        String BOUNDARY = "----------" + System.currentTimeMillis();
        con.setRequestProperty("Content-Type", "multipart/form-data; boundary="
                + BOUNDARY);

        // 请求正文信息

        // 第一部分：
        StringBuilder sb = new StringBuilder();
        sb.append("--"); // ////////必须多两道线
        sb.append(BOUNDARY);
        sb.append("\r\n");
        sb.append("Content-Disposition: form-data;name=\"buffer\";filename=\""
                + name + "\"\r\n");
        sb.append("Content-Type:"+S.avoidNull(type,"image/jpeg")+"\r\n\r\n");

        byte[] head = sb.toString().getBytes("utf-8");

        // 获得输出流

        OutputStream out = new DataOutputStream(con.getOutputStream());
        out.write(head);

        // 文件正文部分
        DataInputStream in = new DataInputStream(inputStream);
        int bytes = 0;
        byte[] bufferOut = new byte[1024];
        while ((bytes = in.read(bufferOut)) != -1) {
            out.write(bufferOut, 0, bytes);
        }
        in.close();

        // 结尾部分
        byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线

        out.write(foot);

        out.flush();
        out.close();
        /**
         *
         * 读取服务器响应，必须读取,否则提交不成功
         */

        StringBuilder respString = new StringBuilder();
        // 定义BufferedReader输入流来读取URL的响应
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                con.getInputStream()));
        String line = null;
        while ((line = reader.readLine()) != null) {
            S.echo(line);
            respString.append(line);
        }
        return JSON.parse(respString.toString());

    }

    /**
     * post 参数格式为json形式
     *
     * @param uri
     * @param params
     * @param cb
     * @throws UnsupportedEncodingException
     */
    public static void postJson(String uri, Map params, Callback<HttpResponse> cb) throws UnsupportedEncodingException {
        HttpPost post = new HttpPost(uri);

        post.setHeader("Connection", "Keep-Alive");
        HttpEntity entity = new StringEntity(JSON.stringify(params), Charset.forName("utf8"));
        post.setEntity(entity);
        post.setHeader("ContentType", MimeTypes.getMimeType("json") + ";charset=utf8");

        try (CloseableHttpClient client = HttpClients.createDefault();
             CloseableHttpResponse resp = client.execute(post)
        ) {
            cb.apply(resp);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * post 参数格式为json形式 返回数据也为json格式
     *
     * @param uri
     * @param params
     * @throws UnsupportedEncodingException
     * @return json格式的resp
     */
    public static Map<String,Object> postJson(String uri, Map params) throws UnsupportedEncodingException {
        HttpPost post = new HttpPost(uri);

        post.setHeader("Connection", "Keep-Alive");
        HttpEntity entity = new StringEntity(JSON.stringify(params), Charset.forName("utf8"));
        post.setEntity(entity);
        post.setHeader("ContentType", MimeTypes.getMimeType("json") + ";charset=utf8");

        try (CloseableHttpClient client = HttpClients.createDefault();
             CloseableHttpResponse resp = client.execute(post)
        ) {
            return parseRespToJson(resp);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * post 参数格式为xml形式
     *
     * @param uri
     * @param inputStream
     * @param cb
     */
    public static void postXml(String uri, InputStream inputStream, Callback<HttpResponse> cb) {
        HttpPost post = new HttpPost(uri);
        post.setHeader("ContentType", MimeTypes.getMimeType("xml") + ";charset=utf8");
        post.setEntity(new InputStreamEntity(inputStream));

        try (CloseableHttpClient client = HttpClients.createDefault();
             CloseableHttpResponse resp = client.execute(post)
        ) {
            cb.apply(resp);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * get 返回数据为json格式
     *
     * @param uri
     * @throws UnsupportedEncodingException
     * @return json格式的resp
     */
    public static Map<String,Object> get(String uri) throws UnsupportedEncodingException {
        HttpGet get=new HttpGet(uri);
        get.setHeader("Connection", "Keep-Alive");
        get.setHeader("ContentType", MimeTypes.getMimeType("json") + ";charset=utf8");

        try (CloseableHttpClient client = HttpClients.createDefault();
             CloseableHttpResponse resp = client.execute(get)
        ) {
            return parseRespToJson(resp);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * get file
     *
     * @param uri
     * @throws UnsupportedEncodingException
     * @return
     */
    public static File getFile(String uri) throws UnsupportedEncodingException {
        HttpGet get=new HttpGet(uri);
        get.setHeader("Connection", "Keep-Alive");
        get.setHeader("ContentType", MimeTypes.getMimeType("json") + ";charset=utf8");

        try (CloseableHttpClient client = HttpClients.createDefault();
             CloseableHttpResponse resp = client.execute(get)
        ) {
            File cache_dir = new File(PATH.classpathRoot(), "cache");
            if(!cache_dir.exists()) cache_dir.mkdir();
            File cache=new File(cache_dir.getAbsolutePath(),S.uuid.str());
            FileOutputStream fos=new FileOutputStream(cache);
            InputStream is=resp.getEntity().getContent();
            byte[] buffer=new byte[1024];
            int i=0;
            while ((i=is.read(buffer))!=-1){
                fos.write(buffer,0,i);
            }
            is.close();
            fos.flush();
            fos.close();
            return cache;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Map<String, Object> parseRespToJson(HttpResponse resp) {
        //postString(WEIXIN_URL,getXmlBody(params),"application/xml;charset=utf8",res->{
        HttpEntity entity = resp.getEntity();
        if (entity == null) {
            throw new RuntimeException("404");
        }
        try {

            String in = S.stream.readFully(entity.getContent(), CharsetUtil.UTF_8);

            Map<String, Object> map = JSON.parse(in);

            if (map == null) {
                throw new RuntimeException("微信通讯失败");
            }
            return map;
        } catch (Exception e) {
            throw new RuntimeException("微信通讯失败");
        }
    }
}
